/*
 * codeGeneration.h
 *
 *  Created on: 1 Apr 2011
 *      Author: phthy08
 */
#include "tree.h"
#include "symbol.h"
#include <malloc.h>
#ifndef __code_h
#define __code_h
#define HEAP_SIZE 100000
typedef struct ll{
	struct ll *next;
	struct ll *previous;
	struct asc *asc;
} ll;
typedef struct asc{
	enum{LABEL, FUNCLABEL, RETURN, MOV_CONST, MOV, MOVEPOS, PUSH, PUSH_CONST, POP, ADD, ADD_CONST, SUB, SUB_CONST, DIV,DIV_CONST, MUL,MUL_CONST, AND, OR, NEG, CMP, CMP_CONST, JMP, JLE, JGE, JA, JG, JL, JAE, JNE, JE, CALL, ALLOC, DEALLOC, STATICLINK} kind;
	union{
		char *id;
		struct{struct reg *first;struct reg *second;}arguments;
		struct{int first;struct reg *second;}arguments_const;
		struct{struct reg *first;struct reg *second;int pos1;int pos2;}regs;
	}par;
}asc;

typedef struct reg{
	int id;
	char *regid;
	int value;
}reg;

ll *codeBODY(BODY *body, SymbolTable *root);
void codeDECL_LIST_FUNC(DECL_LIST *decl_list);
void makeCOUNT_VARS(DECL_LIST *decl_list, SymbolTable *symboltable);
void makeCOUNT_VAR(VAR_DECL_LIST *var_decl_list, SymbolTable *symboltable);
void codeFUNC(FUNCTION *function);
void codeMAKE_POS(VAR_DECL_LIST *var_decl_list, int arguments, SymbolTable *symboltable);
//void codeDECL_LIST_VAR(DECL_LIST *decl_list);
void codeSTATEMENT_LIST(STATEMENT_LIST *statement_list, SymbolTable *root);
void codeSTATEMENT(STATEMENT *statement, SymbolTable *root);
reg *codeEXPRESSION(EXPRESSION *expression, SymbolTable *root);
int codeCOUNT_ARGS(VAR_DECL_LIST *var_decl_list, int argcounter);
reg *codeTERM(TERM *term, SymbolTable *root);
void codeEXP_LIST(EXP_LIST *exp_list, SymbolTable *symboltable);
reg *codeVARIABLE(VARIABLE *variable, SymbolTable *root);
int codeSCOPE(SymbolTable *symboltable, char *name, int scope);
void makeLABEL(char *label);
void makeFUNC_LABEL(char *label);
void makeRETURN();
void makePUSH(reg *arg);
void makePUSH_CONST(int value);
void makeMOV(reg *arg1, reg *arg2);
void makeMOV_CONST(int value, reg *arg2);
void makeMOVEPOS(reg *arg1, reg *arg2, int pos1, int pos2);
void makePOP(reg *arg);
void makeADD(reg *arg1, reg *arg2);
void makeADD_CONST(int value, reg *arg2);
void makeSUB(reg *arg1, reg *arg2);
void makeSUB_CONST(int value, reg *arg2);
void makeDIV(reg *arg1);
void makeDIV_CONST(int value, reg *arg2);
void makeMUL(reg *arg1, reg *arg2);
void makeMUL_CONST(int value, reg *arg2);
void makeAND(reg *arg1, reg *arg2);
void makeOR(reg *arg1, reg *arg2);
void makeNEG(reg *arg);
void makeCMP(reg *arg1, reg *arg2);
void makeCMP_CONST(int value, reg *arg2);
void makeJA(reg *arg1, reg *arg2);
void makeJAE(reg *arg1, reg *arg2);
void makeJG(char *label);
void makeJL(char *label);
void makeJLE(char *label);
void makeJGE(char *label);
void makeJMP(char *label);
void makeJNE(char *label);
void makeJE(char *label);
void makeCALL(char *call);
void makeSAVE_REG();
void makeRESTORE_REG();
void makeALLOC();
void makeDEALLOC();
reg *makeREG(int value);
reg *makeREG_REG();
void makePOP_ESP(int amount);
reg *makeREG_ID(int i,char * name);
void codeALLOCATE(reg *reg_length,reg *reg_var);
#endif
